package com.coderknock.bbs.conf

import com.coderknock.bbs.login.CoderknockAuthenticationProvider
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.web.csrf.CsrfTokenRepository
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository

/**
 * <p></p>
 * @author 三产
 * @version 1.0
 * @date 2017-12-01
 * @QQGroup 213732117
 * @website http://www.coderknock.com
 * @copyright Copyright 2017 拿客 coderknock.com  All rights reserved.
 * @since JDK 1.8
 */
@Configuration
class WebSecurityConfig(val coderknockAuthenticationProvider: CoderknockAuthenticationProvider) : WebSecurityConfigurerAdapter() {

    /**
     * AuthenticationManagerBuilder 参数决定了该方法会被用做权限的管理

     * @param auth
     * *
     * @throws Exception
     */
    override fun configure(auth: AuthenticationManagerBuilder) {
        auth.authenticationProvider(coderknockAuthenticationProvider)
    }

    /**
     * 这里用于配置要忽略的资源验证
     */
    override fun configure(web: WebSecurity) {
        //配置不对静态资源进行权限验证
        web.ignoring().antMatchers("/js/**").and()
                .ignoring().antMatchers("/layui/**").and()
                .ignoring().antMatchers("/images/**").and()
                .ignoring().antMatchers("/mods/**").and()
                .ignoring().antMatchers("/css/**")
    }

    override fun configure(http: HttpSecurity) {
        //layer frame 跨域问题的根源 这里默认是不可访问，需要设置 设置 frame 同域可访问
        http.headers().frameOptions().sameOrigin()
        http.authorizeRequests()
                //设置 admin 路径只能由 ADMIN 权限的人员访问
                .antMatchers("/admin/**").access("hasRole('ADMIN')")
                .antMatchers("/upload/**").anonymous()
                .antMatchers("/user/**").access("hasRole('READER')")
                //注册页面允许任何人访问
                .antMatchers("/register/**").anonymous()
                .and()
                //设置基于表单的登录验证
                .formLogin()
                //设置自定义的登录页面，并且允许所有人员访问
//                .loginPage("/login").permitAll()
                //登录失败跳转的路径
                .failureForwardUrl("/login?error=true")
                //登录成功后的页面，允许所有人访问
                .loginProcessingUrl("/").permitAll()
                .and()
                .logout()
                .logoutUrl("/loginOut")
                .logoutSuccessUrl("/").permitAll()
                .and()
                //允许用户使用HTTP基于验证进行认证
                .httpBasic()
//        http.csrf()
//                .csrfTokenRepository(csrfTokenRepository())

    }

    /**
     * 设置 CSRF 策略
     */
    private fun csrfTokenRepository(): CsrfTokenRepository {
        var repository = HttpSessionCsrfTokenRepository()
        repository.setSessionAttributeName("_csrf")
        return repository
    }
}